package ihm.manes_ho.agenda;

import ihm.manes_ho.agenda.data.HardCodedDB;
import ihm.manes_ho.agenda.dialog.RendezVousDialog;
import ihm.manes_ho.agenda.vo.MeetingItemVO;
import ihm.manes_ho.agenda.vo.MeetingVO;

import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

/**
 * Calendar
 */
public class Calendar extends Activity {
	static final int ADD_RENDEZ_VOUS_DIALOG_ID = 0;
	static final int EDIT_RENDEZ_VOUS_DIALOG_ID = 1;
	private static MeetingVO selectedMeeting;

	/**
	 * weekday column index
	 * <p>
	 * if (value == 0) then display "Mon - Tue - Wed"
	 * <p>
	 * if (value == 1) then display "Tue - Wed - Thu"
	 * <p>...
	 * <p>
	 * if (value == 4) then display "Fri - Sat - Sun"
	 */
	private static int weekday_column_index;

	/**
	 * rendez_vous items id
	 */
	private int[] rendez_vous_item_id_list= {
			R.id.rendez_vous_item0, R.id.rendez_vous_item1, R.id.rendez_vous_item2,
			R.id.rendez_vous_item3, R.id.rendez_vous_item4, R.id.rendez_vous_item5, 
			R.id.rendez_vous_item6, R.id.rendez_vous_item7, R.id.rendez_vous_item8,	
			R.id.rendez_vous_item9, R.id.rendez_vous_item10, R.id.rendez_vous_item11, 
			R.id.rendez_vous_item12, R.id.rendez_vous_item13, R.id.rendez_vous_item14,
			R.id.rendez_vous_item15, R.id.rendez_vous_item16, R.id.rendez_vous_item17
	};
	
	/**
	 * database - hard-coded data
	 */
	private static HardCodedDB database = HardCodedDB.getInstance();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.calendar);

		//init hours
		initHours();

		//init weekdays
		initWeekdays();

		//init rendez vous
		initRendezVous();

		//init back/next buttons
		initButtons();
	}

	/**
	 * init hours left/right bar
	 */
	private void initHours() {
		ArrayAdapter<String> hourAdapter = new ArrayAdapter<String>(
				this, 
				R.layout.list_hour, 
				getResources().getStringArray(R.array.hours)
		);
		((ListView) findViewById(R.id.hours_left)).setAdapter(hourAdapter);
		((ListView) findViewById(R.id.hours_right)).setAdapter(hourAdapter);
	}

	/**
	 * init weekdays header/footer bar
	 */
	private void initWeekdays() {
		ArrayAdapter<String> weekdayAdapter = new ArrayAdapter<String>(
				this, 
				R.layout.list_weekday, 
				getSubArrayOf(getResources().getStringArray(R.array.weekdays), weekday_column_index, 3)
		);

		((GridView) findViewById(R.id.weekdays_header)).setAdapter(weekdayAdapter);
		((GridView) findViewById(R.id.weekdays_footer)).setAdapter(weekdayAdapter);
	}

	/**
	 * init rendez-vous items
	 */
	private void initRendezVous() {
		List<MeetingItemVO> meetingItemList = database.getMeetingItemList(weekday_column_index, 3);

		for (int i = 0; i < 18; i++){
			ArrayAdapter<MeetingVO> arrayAdapter = 
				new RendezVousAdapter(this, R.layout.rendez_vous, meetingItemList.get(i));

			((ListView) findViewById(rendez_vous_item_id_list[i])).setAdapter(arrayAdapter);
		}
	}

	/**
	 * init next/back buttons
	 */
	private void initButtons() {
		View.OnClickListener backListener = new View.OnClickListener() {			
			@Override
			public void onClick(View v) {
				if (weekday_column_index > 0) {
					weekday_column_index--;
					onContentChanged();
				}
			}
		};
		((Button) findViewById(R.id.btn_back_header)).setOnClickListener(backListener);
		((Button) findViewById(R.id.btn_back_footer)).setOnClickListener(backListener);

		View.OnClickListener nextListener = new View.OnClickListener() {			
			@Override
			public void onClick(View v) {
				if (weekday_column_index < 4) {
					weekday_column_index++;
					onContentChanged();
				}
			}
		};
		((Button) findViewById(R.id.btn_next_header)).setOnClickListener(nextListener);
		((Button) findViewById(R.id.btn_next_footer)).setOnClickListener(nextListener);
	}
	
	/**
	 * get a subArray of an array of string 
	 * @param strArr array of string
	 * @param index index of starting element
	 * @param length number of element
	 * @return
	 */
	private String[] getSubArrayOf(String[] strArr, int index, int length) {
		String[] result = new String[length];
		for (int i = 0; i < length; i++) {
			result[i] = strArr[index++];
		}
		return result;
	}

	/**
	 * onCreateDialog - shows either one of the following dialogs:
	 * <p> 1. Dialog of adding a rendez-vous
	 * <p> 2. Dialog of updating a rendez-vous
	 * 
	 * * <p>This method is only called the very FIRST time a dialog is opened
	 * <p> This callback method is passed the same ID that we passed to showDialog(int)
	 * */
	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case ADD_RENDEZ_VOUS_DIALOG_ID:
		case EDIT_RENDEZ_VOUS_DIALOG_ID:
			return new RendezVousDialog(this, id, callBack);
		}
		return null;
	}

	/**
	 * onPrepareDialog
	 */
	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		switch (id) {
		case ADD_RENDEZ_VOUS_DIALOG_ID:			
			break;
		case EDIT_RENDEZ_VOUS_DIALOG_ID:
			((RendezVousDialog) dialog).setData(selectedMeeting);
			break;
		}
	}

	/**
	 * override onContentChanged()
	 * <p>
	 * update both weekdays view & rendez-vous items view
	 */
	@Override
	public void onContentChanged() {
		initWeekdays();
		initRendezVous(); //...without calling this, the 'rendez vous' item view can't update itself,,, why????
		super.onContentChanged();
	}

	/**
	 * the callback is called when the user clicks the Ok button in the dialog (add/update)
	 */
	private RendezVousDialog.OnOkClickListener callBack = new RendezVousDialog.OnOkClickListener() {

		@Override
		public void onOkClick(int type, String name, String address, int weekdayIndex, int timeStart, int timeEnd) {
			switch (type) {
			case ADD_RENDEZ_VOUS_DIALOG_ID:
				database.addMeeting(name, address, weekdayIndex, timeStart, timeEnd);
				onContentChanged();
				break;
			case EDIT_RENDEZ_VOUS_DIALOG_ID:
				selectedMeeting.setName(name);
				selectedMeeting.setAddress(address);
				selectedMeeting.setWeekday_index(weekdayIndex);
				selectedMeeting.setTimeStart(timeStart);
				selectedMeeting.setTimeEnd(timeEnd);
				Log.v("ok", "weekdayIndex : " + weekdayIndex);
				onContentChanged();
				break;
			}	
		}
	};

	/**
	 * onCreateOptionsMenu - creating menu "add" / "remove all" for the calendar
	 */
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.layout.menu, menu);
		return true;
	}
	
	/**
	 * onOptionsItemSelected - called when a menu (add/remove all) is clicked
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.menu_remove_all:
			AlertDialog.Builder builder = new AlertDialog.Builder(Calendar.this);
			builder.setTitle(getResources().getString(R.string.txt_confirmation));
			builder.setMessage(getResources().getString(R.string.txt_confirm_remove_all_rendez_vous));
			builder.setPositiveButton(getResources().getString(R.string.btn_ok), new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					database.removeAllMeetings();
					onContentChanged();                            
				}                        
			});
			builder.setNegativeButton(getResources().getString(R.string.btn_cancel), null);
			builder.show();			
			break;

		case R.id.menu_add:
			showDialog(ADD_RENDEZ_VOUS_DIALOG_ID);
			break;
		}
		return true;
	}

	/**
	 * defines RendezVousAdapter class --- static nested-class
	 * <p> This apdater is passed to a rendez-vous view item which has type of ListView
	 * <p> Each rendez-vous view item (ListView) may have many rendez-vous objects (each which has type of MeetingVO)
	 */
	 private static class RendezVousAdapter extends ArrayAdapter<MeetingVO> {
		 MeetingItemVO meetingItem;
		 int resource;
		 private LayoutInflater mInflater;

		 public RendezVousAdapter(Context context, int textViewResourceId, MeetingItemVO meetingItem) {
			 super(context, textViewResourceId, meetingItem.getMeetingList());
			 this.resource = textViewResourceId;
			 this.meetingItem = meetingItem;
			 mInflater = LayoutInflater.from(context);
		 }    

		 @Override
		 public View getView(final int position, View convertView, ViewGroup parent) {

			 if (convertView == null) {
				 convertView = mInflater.inflate(resource, null);       	
			 }
			 TextView rendez_vous = (TextView) convertView.findViewById(R.id.txt_rendez_vous);

			 rendez_vous.setText(meetingItem.getMeetingList().get(position).toString());
			 rendez_vous.setOnClickListener(new View.OnClickListener() {

				 @Override
				 public void onClick(View v) {
					 selectedMeeting = meetingItem.getMeetingList().get(position);
					 ((Activity) v.getContext()).showDialog(EDIT_RENDEZ_VOUS_DIALOG_ID);
				 }
			 });

			 ImageView delete_icon = (ImageView) convertView.findViewById(R.id.icon_delete);
			 delete_icon.setOnClickListener(new View.OnClickListener() {

				 @Override
				 public void onClick(final View v) {
					 AlertDialog.Builder builder = new AlertDialog.Builder(v.getContext());
					 builder.setTitle(v.getContext().getResources().getString(R.string.txt_confirmation));
					 builder.setMessage(v.getContext().getResources().getString(R.string.txt_confirm_remove_a_rendez_vous));
					 builder.setPositiveButton(v.getContext().getResources().getString(R.string.btn_ok), 
							 new DialogInterface.OnClickListener() {
						 public void onClick(DialogInterface dialog, int which) {
							 meetingItem.removeMeeting(position);
							 ((Activity) v.getContext()).onContentChanged();                         
						 }                        
					 });
					 builder.setNegativeButton(v.getContext().getResources().getString(R.string.btn_cancel), null);
					 builder.show();					
				 }
			 });
			 return convertView;
		 }
	 }
}
